<script setup lang="ts">
import dayjs from 'dayjs'
import { useRequest } from 'vue-request'
import AMapLoader from '@amap/amap-jsapi-loader'
import { useBeforeOrderStore } from '@/store/beforeOrder'
import '@amap/amap-jsapi-types'
import markerIcon from '@/static/images/marker.png'
import { type CalculateOrderPriceAPIParams, calculateOrderPriceAPI } from '@/apis/calculateOrderPrice'
import { useUserInfoStore } from '@/store/userInfo'
import { OrderType } from '@/types/enum'
import { type CreateOrderAPIData, createOrderAPI } from '@/apis/createOrder'
import { payOrderAPI } from '@/apis/payOrder'
import { useOrdersTabSelectionStore } from '@/store/ordersTabSelection'

const router = useRouter()
const userInfoStore = useUserInfoStore()
const beforeOrderStore = useBeforeOrderStore()
const ordersTabSelectionStore = useOrdersTabSelectionStore()

const orderType = ref<OrderType>()

onLoad((options) => {
  if (!options?.order_type) {
    uni.showToast({ title: '获取数据失败', icon: 'none' })
    return
  }
  orderType.value = Number(options.order_type)
})

/* -------------------------------- 地图 START -------------------------------- */
let amap: typeof AMap
let map: AMap.Map
let marker: AMap.Marker

onShow(async () => {
  await loadMap()
  initMap()
  initCenterMarker()
})

/**
 * @description 使用 key 与 securityCode 加载地图
 */
async function loadMap() {
  // 挂载安全密钥
  (window as any)._AMapSecurityConfig = {
    securityJsCode: import.meta.env.VITE_MAP_SECURITY_JS_CODE,
  }
  // 加载地图
  amap = await AMapLoader.load({
    key: import.meta.env.VITE_MAP_KEY,
    version: '2.0',
  })
}

/**
 * @description 初始化地图对象，将地图挂载到对应的 dom 元素中
 */
function initMap() {
  map = new amap.Map('call-map', {
    mapStyle: 'amap://styles/whitesmoke',
    zoom: 14,
    center: [beforeOrderStore.to!.lng, beforeOrderStore.to!.lat],
    dragEnable: false,
    zoomEnable: false,
    rotateEnable: false,
    touchZoom: false,
  })
}

/**
 * @description 初始化一个 Marker，应当始终位于地图中央，当触发地图平移时间时应当更新此 Marker 的位置
 */
function initCenterMarker() {
  marker = new AMap.Marker({
    map,
    position: map.getCenter(),
    anchor: 'bottom-center',
    icon: markerIcon,
  })
  map.add(marker)
}
/* --------------------------------- 地图 END --------------------------------- */

/* -------------------------------- 价格 START -------------------------------- */
const { data: priceData, loading, refreshAsync } = useRequest(
  () => {
    const query: CalculateOrderPriceAPIParams = {
      start_latitude: `${beforeOrderStore.from?.lat}`,
      start_longitude: `${beforeOrderStore.from?.lng}`,
      end_latitude: `${beforeOrderStore.to?.lat}`,
      end_longitude: `${beforeOrderStore.to?.lng}`,
    }
    if (beforeOrderStore.coupon?.id)
      query.coupon_id = `${beforeOrderStore.coupon.id}`

    return calculateOrderPriceAPI(query, userInfoStore.userInfo!.token)
      .then(res => res.data?.data)
  },
  { manual: true },
)

onShow(() => refreshAsync())
/* --------------------------------- 价格 END --------------------------------- */

/* -------------------------------- 优惠券 START ------------------------------- */
const displayedCouponLabel = computed(() => {
  return beforeOrderStore.coupon ? `已选择` : ''
})

function handleSelectCoupon() {
  router.push({
    name: 'couponList',
    params: {
      navigation_destination: 'back',
    },
  })
}
/* --------------------------------- 优惠券 END -------------------------------- */

/* -------------------------------- 备注 START -------------------------------- */
const displayedRemarkLabel = computed(() => {
  return beforeOrderStore.remark ? '已添加' : ''
})

function handleAddRemark() {
  router.push('addRemark')
}
/* --------------------------------- 备注 END --------------------------------- */

/* ------------------------------- 乘车人数 START ------------------------------- */
const displayedPassengerCountLabel = computed(() => {
  return beforeOrderStore.passengerCount ? `乘车${beforeOrderStore.passengerCount}人` : ''
})

const selectedPassengerCountIndex = computed(() => {
  return ['1', '2', '3', '4', '5', '6', '7'].findIndex(el => beforeOrderStore.passengerCount ? el === beforeOrderStore.passengerCount : el === '1')
})
/* -------------------------------- 乘车人数 END -------------------------------- */

/* ------------------------------- 乘车时间 START ------------------------------- */
const displayedDepartureTime = computed(() => {
  if (!beforeOrderStore.departureTime)
    return '随时'
  return beforeOrderStore.departureTime
})

const timePickerRef = ref()

function handleUpdateDepartureTime({ date }: { date: dayjs.Dayjs, str: string }) {
  beforeOrderStore.departureTime = date.format('YYYY-MM-DD HH:mm')
  timePickerRef.value.close()
}
/* -------------------------------- 乘车时间 END -------------------------------- */

function handleViewPriceDescription() {
  router.push({
    name: 'priceDescription',
    params: { type: '包车' },
  })
}

const handleSubmit = useThrottleFn(async () => {
  if (!userInfoStore.userInfo?.mobile || !userInfoStore.userInfo.nickname) {
    uni.showToast({ title: '请先完善个人信息', icon: 'none' })
    return
  }
  if (
    !orderType.value
    || !beforeOrderStore.city
    || !beforeOrderStore.from
    || !beforeOrderStore.to
  ) {
    uni.showToast({ title: '发起失败', icon: 'none' })
    return
  }

  /**
   * 代叫特有的字段：priority_contact
   * 捎件特有的字段：goods_type, images
   */
  const queryData: CreateOrderAPIData = (() => {
    if (orderType.value === OrderType.包车) {
      return {
        type: orderType.value.toString(),
        city: beforeOrderStore.city,
        start_place: beforeOrderStore.from!.name,
        start_place_lng: beforeOrderStore.from!.lng.toString(),
        start_place_lat: beforeOrderStore.from!.lat.toString(),
        end_place: beforeOrderStore.to!.name,
        end_place_lng: beforeOrderStore.to!.lng.toString(),
        end_place_lat: beforeOrderStore.to!.lat.toString(),
        coupon_id: beforeOrderStore.coupon?.id.toString() || null,
        num: beforeOrderStore.passengerCount || '1',
        start_time: beforeOrderStore.departureTime || '随时出发',
        passengers_mobile: userInfoStore.userInfo!.mobile,
        passengers_name: userInfoStore.userInfo!.nickname,
      }
    }
    else if (orderType.value === OrderType.代叫) {
      return {
        type: orderType.value.toString(),
        city: beforeOrderStore.city,
        start_place: beforeOrderStore.from!.name,
        start_place_lng: beforeOrderStore.from!.lng.toString(),
        start_place_lat: beforeOrderStore.from!.lat.toString(),
        end_place: beforeOrderStore.to!.name,
        end_place_lng: beforeOrderStore.to!.lng.toString(),
        end_place_lat: beforeOrderStore.to!.lat.toString(),
        coupon_id: beforeOrderStore.coupon?.id.toString() || null,
        num: beforeOrderStore.passengerCount || '1',
        start_time: beforeOrderStore.departureTime || '随时出发',
        remark: beforeOrderStore.remark || '',
        passengers_mobile: beforeOrderStore.passengerMobile,
        passengers_name: beforeOrderStore.passengerName,
        pronoun_mobile: beforeOrderStore.pronounMobile,
        pronoun_name: beforeOrderStore.pronounName,
        priority_contact: beforeOrderStore.priorityContact,
      }
    }
    else {
      return {
        type: orderType.value.toString(),
        city: beforeOrderStore.city,
        start_place: beforeOrderStore.from!.name,
        start_place_lng: beforeOrderStore.from!.lng.toString(),
        start_place_lat: beforeOrderStore.from!.lat.toString(),
        end_place: beforeOrderStore.to!.name,
        end_place_lng: beforeOrderStore.to!.lng.toString(),
        end_place_lat: beforeOrderStore.to!.lat.toString(),
        coupon_id: beforeOrderStore.coupon?.id.toString() || null,
        num: beforeOrderStore.passengerCount || '1',
        start_time: beforeOrderStore.departureTime || '随时出发',
        remark: beforeOrderStore.remark || '',
        passengers_mobile: beforeOrderStore.passengerMobile,
        passengers_name: beforeOrderStore.passengerName,
        pronoun_mobile: beforeOrderStore.pronounMobile,
        pronoun_name: beforeOrderStore.pronounName,
        goods_type: beforeOrderStore.goodsType,
        images: beforeOrderStore.images.join(',') || '',
      }
    }
  })()

  const res = await createOrderAPI(queryData, userInfoStore.userInfo!.token)
  if (res.data?.code !== 1)
    return
  const payRes = await payOrderAPI({ id: res.data.data }, userInfoStore.userInfo!.token)
  uni.showToast({ title: payRes.data?.msg, icon: 'none' })
  if (payRes.data?.code !== 1)
    return
  WeixinJSBridge.invoke('getBrandWCPayRequest', {
    appId: payRes.data.data.appId,
    timeStamp: payRes.data.data.timeStamp,
    nonceStr: payRes.data.data.nonceStr,
    package: payRes.data.data.package,
    signType: payRes.data.data.signType,
    paySign: payRes.data.data.paySign,
  }, (res: any) => {
    if (res.err_msg === 'get_brand_wcpay_request:ok') {
      beforeOrderStore.$reset()
      ordersTabSelectionStore.selectedSegmentIndex = 0
      ordersTabSelectionStore.selectedTabIndex = 0
      router.pushTab('orders')
      router.push('orderDetail')
    }
    else { uni.showToast({ title: '支付失败', icon: 'none' }) }
  })
}, 1000)
</script>

<template>
  <view class="fixed left-0 right-0 top-0 z-10 h-244rpx from-white to-white from-opacity-80 to-opacity-0 bg-gradient-to-b" />
  <NavigationBar title="一键叫车" />
  <view id="call-map" class="fixed left-0 top-0 h-[70vh] w-screen" />
  <view class="fixed bottom-0 left-0 right-0 flex flex-col items-center rounded-t-50rpx bg-white">
    <view v-if="orderType === OrderType.捎件" class="w-full flex flex-col p-40rpx">
      <view class="text-34rpx font-bold leading-34rpx">
        {{ displayedDepartureTime }}出发
      </view>
      <Spacer height="30" />
      <view class="flex items-center justify-center">
        <view
          class="border-2px border-#FA662F rounded-full border-solid bg-#FCF1E6 px-23rpx py-28rpx text-30rpx text-#FA662F font-medium leading-30rpx"
          @tap="router.back()"
        >
          {{ beforeOrderStore.passengerMobile || '--' }}
        </view>
        <Spacer width="22" />
        <view
          class="border-2px border-#FA662F rounded-full border-solid bg-#FCF1E6 px-23rpx py-28rpx text-30rpx text-#FA662F font-medium leading-30rpx"
          @tap="router.back()"
        >
          修改物品信息
        </view>
        <Spacer width="22" />
        <view
          class="border-2px border-#FA662F rounded-full border-solid bg-#FCF1E6 px-23rpx py-28rpx text-30rpx text-#FA662F font-medium leading-30rpx"
          @tap="handleSelectCoupon"
        >
          优惠券
        </view>
      </view>
    </view>
    <Spacer v-if="orderType !== OrderType.捎件" height="80" />
    <LoadingBuilder :loading="loading">
      <view class="flex flex-col items-center">
        <view class="flex items-baseline" @tap="handleViewPriceDescription">
          <image
            class="mr-12rpx h-30rpx w-30rpx"
            src="@/static/images/warning_orange_circle.png"
          />
          <view class="text-30rpx text-#999999 font-bold leading-30rpx">
            价格
          </view>
          <view class="mx-12rpx text-60rpx text-black font-black leading-60rpx">
            {{ priceData?.total_price.toFixed(2) || '--' }}
          </view>
          <view class="text-30rpx text-#999999 font-bold leading-30rpx">
            元
          </view>
        </view>
        <Spacer height="24" />
        <view class="text-30rpx text-#333333 font-medium leading-30rpx">
          距离 {{ priceData?.distance || '--' }} km
        </view>
      </view>
    </LoadingBuilder>
    <Spacer height="48" />
    <view v-if="orderType !== OrderType.包车" class="w-full px-24rpx" @tap="handleSelectCoupon">
      <view class="w-full flex items-center justify-between rounded-20rpx bg-#F3F3F3 px-30rpx py-37rpx">
        <view class="flex items-center">
          <image
            class="mr-10rpx h-25rpx w-35rpx"
            src="@/static/images/coupon_icon_outline.png"
          />
          <view v-if="beforeOrderStore.coupon" class="text-28rpx text-#333333 font-medium leading-28rpx">
            {{ beforeOrderStore.coupon.name }}
          </view>
          <view v-else class="text-28rpx text-#999999 font-medium leading-28rpx">
            选择优惠券
          </view>
        </view>
        <view class="flex items-center">
          <view v-if="beforeOrderStore.coupon" class="text-28rpx text-#333333 font-medium leading-28rpx">
            {{ `-${beforeOrderStore.coupon.complete_money}` }}
          </view>
          <Spacer width="12" />
          <image
            class="h-22rpx w-12rpx"
            src="@/static/images/cheveron-right.png"
          />
        </view>
      </view>
    </view>
    <Spacer height="67" />
    <view v-if="orderType === OrderType.包车 || orderType === OrderType.代叫" class="w-full flex items-center">
      <CallTagItem
        v-if="orderType === OrderType.包车"
        :value="displayedCouponLabel"
        placeholder="请选择优惠券"
        @tap="handleSelectCoupon"
      />
      <CallTagItem
        v-if="orderType === OrderType.代叫"
        :value="displayedRemarkLabel"
        placeholder="添加备注"
        @tap="handleAddRemark"
      />
      <view class="h-27rpx w-1rpx bg-#C2C2C2" />
      <picker
        :value="selectedPassengerCountIndex"
        :range="['1', '2', '3', '4', '5', '6', '7']"
        @change="(e: any) => beforeOrderStore.passengerCount = (e.detail.value + 1).toString()"
      >
        <CallTagItem :value="displayedPassengerCountLabel" placeholder="请选择乘车人数" />
      </picker>
      <view class="h-27rpx w-1rpx bg-#C2C2C2" />
      <CallTagItem :value="`${displayedDepartureTime}出发`" placeholder="请选择出发时间" @tap="timePickerRef.open()" />
    </view>
    <Spacer v-if="orderType === OrderType.包车 || orderType === OrderType.代叫" height="50" />
    <RGButton @tap="handleSubmit">
      确认叫车
    </RGButton>
    <Spacer height="44" />
  </view>

  <uv-popup ref="timePickerRef" mode="bottom" round="50rpx">
    <TimePicker :initial-value="dayjs()" @confirm="handleUpdateDepartureTime" />
  </uv-popup>
</template>

<route lang="yaml">
name: 'call'
style:
  navigationStyle: 'custom'
</route>
